/*************************************************************************
 *                                                                       *
 * This file is part of the FreeMAPs distribution.  For full copyright   *
 * information, see COPYRIGHT and COPYING.LESSER.                        *
 *                                                                       *
 * Author:           sqbang                                              *
 * Email:            sqbang@ustc.edu                                     *
 * Date:             2012.12.20                                          *
 *                                                                       *
 *************************************************************************/

#ifndef FreeMAPs_include_COMMON_bdry_IrregularBoundaryConditionRange_h
#define FreeMAPs_include_COMMON_bdry_IrregularBoundaryConditionRange_h

#include "FreeMAPsConfig.h"

//C++ headers
#include <vector>
#include <map>

//SAMRAI headers
#ifdef FREEMAPS_HAVE_SAMRAI
#  include "SAMRAI/hier/Patch.h"
#  include "SAMRAI/pdat/CellIndex.h"
#endif

//COMMON headers
#include "COMMON/base/StateIndicator.h"


namespace FreeMAPs
{

//forward delcaration
class AnalyticFunction;
class Point;
class UnstructuredMesh;
/**
 * when impose boundary condition, one should describe the range that
 * the boundary condition applied on. In FreeMAPs, the boundary is described
 * by a level set's zero contour. so use the level set's information to
 * describe complex range is possible.
 *
 * when impose boundary conditions, it loop on the lsm_boundaries that
 * get from boundary_names. on each cell on the boundary, if it is in d_range,
 * then it will be imposed boundary condition. and it will
 * loop up the d_on_level_set_boundaries to see if it is require_inversion.
 *
 * @see IrregularBoundary.h
 * @see IrregularBoundaryConditionStrategy.h
 */
class IrregularBoundaryConditionRange : public StateIndicator
{
public:

    explicit
    IrregularBoundaryConditionRange (
            const std::string& parent_name,
            const std::string& object_name,
            const bool use_structured_mesh,
            bool is_registered_in_info_manager);

    virtual
    ~IrregularBoundaryConditionRange();

public:
    inline const std::set<std::string>&
    get_boundary_names() const;

    inline void
    add_boundary_names(
            const std::set<std::string>& boundary_names);

    inline const
    std::string& get_range() const;

    inline void
    set_range(
            const std::string& range);

public:
    void
    clear();

    void
    get_from_input (
        const InputDatabase* db);

    friend std::ostream&
    operator << (
        std::ostream& os,
        const IrregularBoundaryConditionRange& rhs);


private:

    typedef StateIndicator Parent;

    bool d_use_structured_mesh;

    /*
     * the lsm_boundaries that should impose the boundary conditions.
     * get from boundary condition's input information.
     * if not set, all cells in d_on_level_set_boundaries will be used.
     */
    //sometime it's region
    std::set<std::string> d_boundary_names;

    std::string d_range;

private:

    DISALLOW_COPY_AND_ASSIGN (IrregularBoundaryConditionRange);
};

}

#include "COMMON/bdry/IrregularBoundaryConditionRange.inl"

#endif
